########################################################
###############      TP Image     ######################
########################################################








#######################
## II A vous de jouer #
#######################



##1 importation des bibliothèques

import numpy as np
import imageio as im 
import matplotlib.cm as cm
import matplotlib.pyplot as plt

##2-3 importation/enregistrement/affichage de l'image

image_brute = im.imread('C:/Users/francis/Documents/PAGAUD PC_É/Prépa PC étoile/Info/vache.jpg')
plt.imshow(image_brute)
plt.show()


## 4 Fonction affiche 


def affiche(image, nom_de_la_figure,gris=False) : 
    '''cette fct traite l'affichage du tableau tableau_int associé à l'image 
    elle affiche en couleur ou en niveau de gris selon le booléen gris
    
    entrée : tableau_int de type int32
             nom_de_la_figure est une ch de caractère (titre de l'image)
             gris est un booléen (valant False par défaut) indiquant si on souhaite un affichage en couleur ou en niveaux de gris
             
    pas de sortie
    
    mais cette fct provoque un affichage '''
    plt.figure(nom_de_la_figure)
    if not gris :
        plt.imshow(image.astype(np.uint8))
    else :
        plt.imshow(image.astype(np.uint8), cmap = cm.gray)
    plt.show()
    return ()
    
    
## test 

print(affiche(image_brute, 'La vache'))


###############
## III Quelques Manipulations
###############

##1 

print(np.shape(image_brute))
print(image_brute[0, -1, :])


##2 composantes RGB

copie_1 = image_brute.copy()
copie_2 = image_brute.copy()
copie_3 = image_brute.copy()

copie_1[:, :, 1] = 0
#copie_1[:, :, 2] = 0
affiche(copie_1, 'Vache rouge')

copie_2[:, :, 0] = 0
copie_2[:, :, 2] = 0
affiche(copie_2, 'Vache verte')

copie_3[:, :, 1] = 0
copie_3[:, :, 0] = 0
affiche(copie_3, 'Vache bleue')



##3 trait noir centré

image_rayee = image_brute.copy()
h = np.shape(image_brute)[0]
image_rayee[h//2-1:h//2+1,: ,:] = 0
affiche(image_rayee, 'Image rayée')


##4 négatif

image_negatif = image_brute.copy()
image_negatif = 255 - image_negatif
affiche(image_negatif, 'Négatif')



### Opérations de base

## 1)

def change_luminosite_boucles(image, decalage) :
    """ image un tableau en int
        decalage un entier entre -255 et 255
        affiche l'image avec un changement de luminosité"""
    rep = image.copy()
    rep = rep.astype(np.int)
    rep += decalage
    for i in range (np.shape(rep)[0]) :
        #print(i)
        for k in range (np.shape(rep)[1]) :
            for l in range (np.shape(rep)[2]) :
                if rep[i, k, l] > 255 :
                    rep[i, k, l] = 255
                elif rep[i, k, l] < 0 :
                    rep[i, k, l] = 0
    affiche(rep, 'Changement de luminosité')
    return()

change_luminosite_boucles(image_brute, -100)

## Vectorisé


def change_luminosite_boucles_vector(image, decalage) :
    """ image un tableau en int (représentant une image en couleurs)
        decalage un entier entre -255 et 255
        affiche l'image avec un changement de luminosité"""
    rep = image.copy()
    rep = rep.astype(np.int)
    rep += decalage
    min = np.zeros((np.shape(image)[0], np.shape(image)[1], np.shape(image)[2]))
    max = 255*np.ones((np.shape(image)[0], np.shape(image)[1], np.shape(image)[2]))
    rep = np.fmin(rep, max)
    rep = np.fmax(rep, min)
    affiche(rep, 'Changement de luminosité v')
    return()

change_luminosite_boucles_vector(image_brute, 70)
"""L'affichage est cette fois-ci instantané"""
    
## 2)

def convertion_niveaux_gris(image) :
    """Prend en argument un tableau qui représente une image.
        Affiche cette image en niveaux de gris."""
    rep = image.copy()
    rep_1 = rep[:, :, 0]
    for i in range(np.shape(rep_1)[0]) :
        for k in range(np.shape(rep_1)[1]) :
            rep_1[i, k] = int(0.299*rep[i, k, 0]+0.587*rep[i, k, 1]+0.114*rep[i, k, 2])
    im.imsave('D:/Prépa PC étoile/Info/grisette.jpg', rep_1)
    return(rep_1)

grisette = convertion_niveaux_gris(image_brute)
affiche(grisette, "Niveaux de gris", True)


## 3)

def seuil(image, I_seuil) :
    """Prend en argument :  -un tableau qui représente une image en niveaux de gris
                            -un entier entre 0 et 255 (valeur seuil)
        Renvoie une image dont les valeurs des pixels au-dessus de la valeur seuil sont blancs, et les autres noirs. """
    gris = convertion_niveaux_gris(image)
    for i in range(np.shape(gris)[0]) :
        for j in range(np.shape(gris)[1]) :
            if gris[i,j]<I_seuil :
                gris[i,j] = 0
            else :
                gris[i,j] = 255
    affiche(gris, "Image noir et blanc", True)
    return()
    
seuil(image_brute, 150)


## 4)

def augmente_contraste(image, min, max) :
    pente = 255/(max-min)
    rep = convertion_niveaux_gris(image)
    rep = rep.astype(np.int)
    for i in range (np.shape(rep)[0]) :
        for k in range (np.shape(rep)[1]) :
            if rep[i, k] <= min :
                rep[i, k] = 0
            elif rep[i, k] > max :
                rep[i, k] = 255
            else :
                rep[i, k] = int(rep[i, k]*pente)
    affiche(rep, 'Changement de contraste', True)

augmente_contraste(image_brute, 100, 150)